{*********************************************************************
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Autor: Brovin Y.D.
 * E-mail: y.brovin@gmail.com
 *
 ********************************************************************}

unit FGX.ProgressDialog.iOS;

interface

uses
  System.UITypes, System.UIConsts, FGX.ProgressDialog, iOSapi.UIKit,
  FGX.ProgressDialog.Types;

const
  SHADOW_ALPHA = 180;

type

  { TIOSProgressDialogService }

  TIOSProgressDialogService = class (TInterfacedObject, IFGXProgressDialogService)
  public
    { IFGXProgressDialogService }
    function CreateNativeProgressDialog: TfgNativeProgressDialog;
    function CreateNativeActivityDialog: TfgNativeActivityDialog;
  end;

  TiOSNativeActivityDialog = class (TfgNativeActivityDialog)
  private
    FAniIndicator: UIActivityIndicatorView;
    FShadowColor: TAlphaColor;
    FShadowView: UIView;
    FLabelView: UILabel;
  protected
    procedure SetMessage(const Value: string); override;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Show; override;
    procedure Hide; override;
  end;

  TiOSNativeProgressDialog = class (TfgNativeProgressDialog)
  private
    FProgressBar: UIProgressView;
    FShadowColor: TAlphaColor;
    FShadowView: UIView;
    FLabelView: UILabel;
  protected
    procedure SetMessage(const Value: string); override;
    procedure SetProgress(const Value: Single); override;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Show; override;
    procedure Hide; override;
  end;

procedure RegisterService;

var
  ProgressDialogService: TIOSProgressDialogService;

implementation

uses
  FMX.Platform, FMX.Platform.iOS, FMX.Forms, FMX.Helpers.iOS,
  FGX.Helpers.iOS,
  System.Types,
  iOSapi.CoreGraphics, iOSapi.Foundation;

procedure RegisterService;
begin
  ProgressDialogService := TIOSProgressDialogService.Create;
  TPlatformServices.Current.AddPlatformService(IFGXProgressDialogService, ProgressDialogService);
end;

{ TIOSProgressDialogService }

function TIOSProgressDialogService.CreateNativeActivityDialog: TfgNativeActivityDialog;
begin
  Result := TiOSNativeActivityDialog.Create;
end;

function TIOSProgressDialogService.CreateNativeProgressDialog: TfgNativeProgressDialog;
begin
  Result := TiOSNativeProgressDialog.Create;
end;

{ TiOSNativeProgressDialog }

constructor TiOSNativeActivityDialog.Create;
var
  ScreenBounds: NSSize;
  CenterPoint: NSPoint;
begin
  inherited Create;
  FShadowColor := MakeColor(0, 0, 0, SHADOW_ALPHA);

  { Shadow }
  ScreenBounds := MainScreen.bounds.size;
  FShadowView := TUIView.Alloc;
  FShadowView.setUserInteractionEnabled(True);
  FShadowView := TUIView.Wrap(FShadowView.initWithFrame(CGRectMake(0, 0, ScreenBounds.Width, ScreenBounds.Height)));
  FShadowView.setHidden(True);
  FShadowView.setAutoresizingMask(UIViewAutoresizingFlexibleWidth or UIViewAutoresizingFlexibleHeight);
  FShadowView.setBackgroundColor(ColorToNSColor(FShadowColor));

  CenterPoint := FShadowView.center;
  { Creating Ani indicator }
  FAniIndicator := TUIActivityIndicatorView.Alloc;
  FAniIndicator.initWithActivityIndicatorStyle(UIActivityIndicatorViewStyleWhite);
  FAniIndicator.startAnimating;
  FAniIndicator.setCenter(CGPointMake(CenterPoint.X, CenterPoint.Y - FAniIndicator.bounds.size.height - 5));

  { Creating message label }
  FLabelView := TUILabel.Create;
  FLabelView.setTextColor(TUIColor.Wrap(TUIColor.OCClass.whiteColor));
  FLabelView.setBackgroundColor(TUIColor.Wrap(TUIColor.OCClass.clearColor));
  FLabelView.setFont(FLabelView.font.fontWithSize(15.0));
  FLabelView.setBounds(CGRectMake(0, 0, FShadowView.bounds.size.width, 25));
  FLabelView.setTextAlignment(UITextAlignmentCenter);
  FLabelView.setCenter(CGPointMake(CenterPoint.X, CenterPoint.Y + 5));

  { Adding view }
  FShadowView.addSubview(FAniIndicator);
  FShadowView.addSubview(FLabelView);
end;

destructor TiOSNativeActivityDialog.Destroy;
begin
  FShadowView.release;
  FAniIndicator.release;
  inherited Destroy;
end;

procedure TiOSNativeActivityDialog.Hide;
begin
  Assert(FShadowView <> nil);

  FShadowView.setHidden(False);
  FShadowView.setAlpha(1.0);
  TUIView.OCClass.beginAnimations(nil, nil);
  try
    TUIView.OCClass.setAnimationDuration(DEFAULT_ANIMATION_DURATION);
    FShadowView.setAlpha(0.0);
  finally
    TUIView.OCClass.commitAnimations;
  end;
end;

procedure TiOSNativeActivityDialog.SetMessage(const Value: string);
begin
  Assert(FLabelView <> nil);

  inherited SetMessage(Value);
  FLabelView.setText(NSSTR(Message));
  Application.ProcessMessages;
end;

procedure TiOSNativeActivityDialog.Show;
begin
  Assert(FShadowView <> nil);
  Assert(FLabelView <> nil);

  FLabelView.setText(NSStr(Message));

  FShadowView.setHidden(False);
  FShadowView.setAlpha(0.0);
  SharedApplication.keyWindow.rootViewController.view.AddSubview(FShadowView);
  TUIView.OCClass.beginAnimations(nil, nil);
  try
    TUIView.OCClass.setAnimationDuration(DEFAULT_ANIMATION_DURATION);
    FShadowView.setAlpha(1.0);
  finally
    TUIView.OCClass.commitAnimations;
  end;

  // We should call it once for starting animation
  Application.ProcessMessages;
end;

{ TiOSNativeProgressDialog }

constructor TiOSNativeProgressDialog.Create;
var
  ScreenBounds: NSSize;
  CenterPoint: NSPoint;
begin
  inherited Create;
  FShadowColor := MakeColor(0, 0, 0, SHADOW_ALPHA);

  { Shadow }
  ScreenBounds := MainScreen.bounds.size;
  FShadowView := TUIView.Alloc;
  FShadowView.setUserInteractionEnabled(True);
  FShadowView := TUIView.Wrap(FShadowView.initWithFrame(CGRectMake(0, 0, ScreenBounds.Width, ScreenBounds.Height)));
  FShadowView.setHidden(True);
  FShadowView.setAutoresizingMask(UIViewAutoresizingFlexibleWidth or UIViewAutoresizingFlexibleHeight);
  FShadowView.setBackgroundColor(ColorToNSColor(FShadowColor));

  CenterPoint := FShadowView.center;

  { Creating message label }
  FLabelView := TUILabel.Create;
  FLabelView.setBackgroundColor(TUIColor.Wrap(TUIColor.OCClass.clearColor));
  FLabelView.setTextColor(TUIColor.Wrap(TUIColor.OCClass.whiteColor));
  FLabelView.setBounds(CGRectMake(0, 0, FShadowView.bounds.size.width, 20));
  FLabelView.setTextAlignment(UITextAlignmentCenter);
  FLabelView.setFont(FLabelView.font.fontWithSize(15.0));
  FLabelView.setCenter(CGPointMake(CenterPoint.X, CenterPoint.Y - FLabelView.bounds.size.height));

  { Creating Ani indicator }
  FProgressBar := TUIProgressView.Alloc;
  FProgressBar.initWithProgressViewStyle(UIProgressViewStyleDefault);
  FProgressBar.setBounds(CGRectMake(0, 0, 200, 20));
  FProgressBar.setCenter(CGPointMake(CenterPoint.X, CenterPoint.Y));

  { Adding view }
  FShadowView.addSubview(FProgressBar);
  FShadowView.addSubview(FLabelView);
end;

destructor TiOSNativeProgressDialog.Destroy;
begin

  inherited;
end;

procedure TiOSNativeProgressDialog.Hide;
begin
  Assert(FShadowView <> nil);

  FShadowView.setHidden(False);
  FShadowView.setAlpha(1.0);
  TUIView.OCClass.beginAnimations(nil, nil);
  try
    TUIView.OCClass.setAnimationDuration(DEFAULT_ANIMATION_DURATION);
    FShadowView.setAlpha(0.0);
  finally
    TUIView.OCClass.commitAnimations;
  end;
end;

procedure TiOSNativeProgressDialog.SetMessage(const Value: string);
begin
  Assert(FLabelView <> nil);

  inherited SetMessage(Value);
  FLabelView.setText(NSSTR(Message));
  Application.ProcessMessages;
end;

procedure TiOSNativeProgressDialog.SetProgress(const Value: Single);
begin
  Assert(FProgressBar <> nil);

  inherited SetProgress(Value);
  FProgressBar.setProgress(Value / 100, True);
  Application.ProcessMessages;
end;

procedure TiOSNativeProgressDialog.Show;
begin
  Assert(FShadowView <> nil);
  Assert(FLabelView <> nil);

  FShadowView.setHidden(False);
  FShadowView.setAlpha(0.0);
  SharedApplication.keyWindow.rootViewController.view.AddSubview(FShadowView);
  TUIView.OCClass.beginAnimations(nil, nil);
  try
    TUIView.OCClass.setAnimationDuration(DEFAULT_ANIMATION_DURATION);
    FShadowView.setAlpha(1.0);
  finally
    TUIView.OCClass.commitAnimations;
  end;

  Application.ProcessMessages;
end;

end.
